﻿// client.cpp : Defines the entry point for the application.
//

#include "stdafx.h"
#include "client.h"

#include <WindowsX.h>
#include <WinSock2.h>
#pragma comment(lib,"WS2_32.lib")
#define MAX_LOADSTRING 100
#include <AtlConv.h>
#include <process.h>
#include <commctrl.h>
#pragma comment(lib,"comctl32.lib")
#include <winuser.h>
#pragma comment(lib,"winmm.lib")
#include <mmsystem.h>

// Global Variables:
HINSTANCE hInst;								// current instance
TCHAR szTitle[MAX_LOADSTRING];					// The title bar text
TCHAR szWindowClass[MAX_LOADSTRING];			// the main window class name
SOCKET client;
HANDLE hEventRegister, hEventPlay, hEventAnswer;
PAINTSTRUCT ps;
HDC hdc;
// Forward declarations of functions included in this code module:
ATOM				MyRegisterClass(HINSTANCE hInstance);
BOOL				InitInstance(HINSTANCE, int);
LRESULT CALLBACK	WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK	About(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK	SignInProc(HWND , UINT , WPARAM , LPARAM );

void threadConnect(PVOID hWnd);
void threadRegister(PVOID nickName);
int APIENTRY _tWinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPTSTR    lpCmdLine,
                     int       nCmdShow)
{
	UNREFERENCED_PARAMETER(hPrevInstance);
	UNREFERENCED_PARAMETER(lpCmdLine);

 	// TODO: Place code here.
	MSG msg;
	HACCEL hAccelTable;

	// Initialize global strings
	LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
	LoadString(hInstance, IDC_CLIENT, szWindowClass, MAX_LOADSTRING);
	MyRegisterClass(hInstance);

	// Perform application initialization:
	if (!InitInstance (hInstance, nCmdShow))
	{
		return FALSE;
	}

	hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_CLIENT));

	// Main message loop:
	while (GetMessage(&msg, NULL, 0, 0))
	{
		if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
	}

	return (int) msg.wParam;
}



//
//  FUNCTION: MyRegisterClass()
//
//  PURPOSE: Registers the window class.
//
//  COMMENTS:
//
//    This function and its usage are only necessary if you want this code
//    to be compatible with Win32 systems prior to the 'RegisterClassEx'
//    function that was added to Windows 95. It is important to call this function
//    so that the application will get 'well formed' small icons associated
//    with it.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
	WNDCLASSEX wcex;

	wcex.cbSize = sizeof(WNDCLASSEX);

	wcex.style			= CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc	= WndProc;
	wcex.cbClsExtra		= 0;
	wcex.cbWndExtra		= 0;
	wcex.hInstance		= hInstance;
	wcex.hIcon			= LoadIcon(hInstance, MAKEINTRESOURCE(IDI_CLIENT));
	wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);
	wcex.hbrBackground	= (HBRUSH)(COLOR_WINDOW+0);
	wcex.lpszMenuName	= MAKEINTRESOURCE(IDC_CLIENT);
	wcex.lpszClassName	= szWindowClass;
	wcex.hIconSm		= LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

	return RegisterClassEx(&wcex);
}

//
//   FUNCTION: InitInstance(HINSTANCE, int)
//
//   PURPOSE: Saves instance handle and creates main window
//
//   COMMENTS:
//
//        In this function, we save the instance handle in a global variable and
//        create and display the main program window.
//
HWND hWnd;
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
   
	
   hInst = hInstance; // Store instance handle in our global variable

   hWnd = CreateWindow(szWindowClass, szTitle, WS_SYSMENU | WS_CAPTION,
      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
 
   hEventRegister = CreateEvent(NULL,TRUE,FALSE,NULL);
   hEventPlay = CreateEvent(NULL,TRUE,FALSE,NULL);
   hEventAnswer = CreateEvent(NULL,FALSE,FALSE,NULL);
   if (!hWnd)
   {
      return FALSE;
   }
   DialogBox(hInst,MAKEINTRESOURCE(IDD_DIALOG1),hWnd,SignInProc); 
  
   _beginthread(threadConnect,0,hWnd);
  

 
   
  // ShowWindow(hWnd,SW_HIDE);
   return TRUE;
}

//
//  FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
//
//  PURPOSE:  Processes messages for the main window.
//
//  WM_COMMAND	- process the application menu
//  WM_PAINT	- Paint the main window
//  WM_DESTROY	- post a quit message and return
//
//
HWND hButtonQ;//hButton ->Connect to server,hButton1->Register nick name,hButton2->Quit Game
HWND hButtonA,hButtonB,hButtonC,hButtonD,hButtonF;
HWND hEditQues,hAnswerArea;
HWND hCaseA, hCaseB,hCaseC ,hCaseD;
HWND hNick;
BOOL OnCreate(HWND hWnd, LPCREATESTRUCT lpCreateStruct)
{
	InitCommonControls();
	
	

	hButtonQ = CreateWindow(_T("BUTTON"),L"Quit",WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 750,400,60,25,hWnd,(HMENU)ID_BUTTONQ,hInst,NULL);
	hButtonF = CreateWindow(_T("BUTTON"),L"Forward",WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 750,90,60,25,hWnd,(HMENU)ID_BUTTONF,hInst,NULL);
	hButtonA = CreateWindow(_T("BUTTON"),L"A",WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 750,150,60,25,hWnd,(HMENU)ID_BUTTONA,hInst,NULL);
	hButtonB = CreateWindow(_T("BUTTON"),L"B",WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 750,180,60,25,hWnd,(HMENU)ID_BUTTONB,hInst,NULL);
	hButtonC = CreateWindow(_T("BUTTON"),L"C",WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 750,210,60,25,hWnd,(HMENU)ID_BUTTONC,hInst,NULL);
	hButtonD = CreateWindow(_T("BUTTON"),L"D",WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 750,240,60,25,hWnd,(HMENU)ID_BUTTOND,hInst,NULL);

	// cau hoi
	hEditQues = CreateWindow(_T("EDIT"),L"",WS_CHILD | WS_VISIBLE |WS_BORDER
    |WS_DISABLED	|ES_MULTILINE | WS_VSCROLL, 30,30,640,240,hWnd,(HMENU)ID_EDITQUES,hInst,NULL);
	
	// luu cau tra loi ( ko hien thi )
	hAnswerArea=CreateWindow(_T("edit"),L"",WS_CHILD, 0,0,0,0,hWnd,NULL,hInst,NULL);
		
	//cac dap an
	hCaseA = CreateWindow(_T("edit"),NULL,WS_CHILD|WS_VISIBLE|WS_BORDER|ES_MULTILINE|WS_DISABLED ,30,280,310,40,hWnd,NULL,hInst,NULL);
	hCaseB =CreateWindow(_T("edit"),NULL,WS_CHILD|WS_VISIBLE|WS_BORDER|ES_MULTILINE|WS_DISABLED ,360,280,310,40,hWnd,NULL,hInst,NULL);
	hCaseC =CreateWindow(_T("edit"),NULL,WS_CHILD|WS_VISIBLE|WS_BORDER|ES_MULTILINE|WS_DISABLED ,30,340,310,40,hWnd,NULL,hInst,NULL);
	hCaseD =CreateWindow(_T("edit"),NULL,WS_CHILD|WS_VISIBLE|WS_BORDER|ES_MULTILINE|WS_DISABLED ,360,340,310,40,hWnd,NULL,hInst,NULL);
	return TRUE;
	
}
void threadRegister(PVOID nickName)
{
	WaitForSingleObject(hEventRegister,INFINITE);
	int number;
	LPTSTR temp;
	temp = new TCHAR[100];
	LPSTR buff;
	CHAR result[sizeof(int)];

	//======================================================
	//Register
	temp = (LPTSTR)nickName;
	//Lay  nick
	
	USES_CONVERSION;
	buff = T2A(temp);
	
	//Send cho server
	send(client,buff,100,0);
	//Nhan result thong bao dang ki
	recv(client,result,3,0);
	number = atoi(result);
	if(number > 0)
	{
		
		SetEvent(hEventPlay);
		ShowWindow(hWnd, SW_RESTORE);
		UpdateWindow(hWnd);

	}
	else
	{
		if(number == -3)
			{
			MessageBox((HWND)hWnd,_T("Đã hết slot trống!"),_T("Server"),MB_OK);
			SendMessage((HWND)hWnd,WM_DESTROY,0,0);
			}
		if(number == -2)
			MessageBox((HWND)hWnd,_T("Nick name bị trùng, hãy nhập lại!"),_T("Server"),MB_OK);
		if(number == -1)
			MessageBox((HWND)hWnd,_T("Bạn vẫn chưa nhập nick name!"),_T("Server"),MB_OK);
		if(number == 0)
			MessageBox((HWND)hWnd,_T("Nick name của bạn có kí tự không hợp lệ!"),_T("Server"),MB_OK);
		SetEvent(hEventRegister);
		
		DialogBox(hInst,MAKEINTRESOURCE(IDD_DIALOG1),(HWND)hWnd,SignInProc);
		
	}
	return;
}
void threadConnect(PVOID hWnd)
{
	//=====================================================
	//Tao socket client
	WSADATA wsadata;
	WSAStartup(MAKEWORD(2,0),&wsadata);
	struct sockaddr_in clientaddr;
	memset(&clientaddr,0,sizeof(clientaddr));

	clientaddr.sin_family = AF_INET;
	clientaddr.sin_port = 1234;
	clientaddr.sin_addr.s_addr = inet_addr("127.0.0.1");

	client = socket(AF_INET,SOCK_STREAM,IPPROTO_IP);
	//======================================================
	int result = connect(client,(sockaddr *)&clientaddr,sizeof(clientaddr));
	if(result!=0 || result == WSAECONNREFUSED)
	{
		
		Sleep(500);
		MessageBox((HWND)hWnd,_T("Không thể kết nối tới server!"),_T("ERROR"),MB_OK);
		SendMessage((HWND)hWnd,WM_DESTROY,0,0);
	}
	else
	//Connect success!
	{
		// goi threadRegister
		SetEvent(hEventRegister);
	}
	WaitForSingleObject(hEventPlay,INFINITE);

	//close thread register then wait ... for question from server
	
	
	BOOL repeat = FALSE;
	do{
		char * buff= new char[2000];
		recv(client,buff,strlen(buff),0);
		
		PlaySound(TEXT("game.wav"),NULL, SND_FILENAME | SND_ASYNC) ;
		char *secondBuff ;
		LPTSTR printQuestion = new TCHAR [strlen(buff)];
		secondBuff = strtok(buff,"|");
		secondBuff = strtok(NULL,"|");
		
		USES_CONVERSION;
		printQuestion = A2T(secondBuff);
		SetWindowText(hEditQues,printQuestion);// take question

		secondBuff = strtok(NULL,"|");
		printQuestion = A2T(secondBuff);
		SetWindowText(hCaseA,printQuestion);// take A answer

		secondBuff = strtok(NULL,"|");
		printQuestion = A2T(secondBuff);
		SetWindowText(hCaseB,printQuestion);// take B answer

		secondBuff = strtok(NULL,"|");
		printQuestion = A2T(secondBuff);
		SetWindowText(hCaseC,printQuestion);// take C answer

		secondBuff = strtok(NULL,"|");
		printQuestion = A2T(secondBuff);
		SetWindowText(hCaseD,printQuestion);// take D answer

		WaitForSingleObject(hEventAnswer,INFINITE);

		TCHAR buffer[2];
		GetWindowText(hAnswerArea,buffer,2);
		char *sender;
		char *receiver = new char[2];

		sender = T2A(buffer);

		send(client,sender,strlen(sender),0);
		recv(client,receiver,2,0);

		if(strlen(receiver)==0)
		{
			MessageBox((HWND)hWnd,L"dut ket noi",NULL,NULL);
			repeat = FALSE;
		}
		else
		{
			if(receiver[0]=='L')
			{
				MessageBox((HWND)hWnd,L"You lose!",NULL,NULL);
				
				repeat = FALSE;
			}
			else
			{
				if(receiver[0]=='W')
				{
					MessageBox((HWND)hWnd,L"You win!",NULL,NULL);

					repeat = FALSE;
				}
				else
				{
					if(receiver[0]=='N')
					{
						MessageBox((HWND)hWnd,L"cau hoi tiep theo",NULL,NULL);
					}
					repeat = TRUE;
				}
			}
		}
		delete buff;
		delete receiver;
	}while(repeat);
	SendMessage((HWND)hWnd,WM_DESTROY,0,0);

	return;
}



LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	int wmId, wmEvent;
	
	switch (message)
	{
	HANDLE_MSG(hWnd,WM_CREATE,OnCreate);
	
	case WM_COMMAND:
		wmId    = LOWORD(wParam);
		wmEvent = HIWORD(wParam);
		// Parse the menu selections:
		switch (wmId)
		{
		case ID_BUTTON1:
			{
				
			}break;
	
		case ID_BUTTONA:
			{
				SetWindowText(hAnswerArea,L"A");
				SetEvent(hEventAnswer);
			}break;
		case ID_BUTTONB:
			{
				SetWindowText(hAnswerArea,L"B");
				SetEvent(hEventAnswer);
			}break;
		case ID_BUTTONC:
			{
				SetWindowText(hAnswerArea,L"C");
				SetEvent(hEventAnswer);
			}break;
		case ID_BUTTOND:
			{
				SetWindowText(hAnswerArea,L"D");
				SetEvent(hEventAnswer);
			}break;
		case ID_BUTTONF:
			{
				SetWindowText(hAnswerArea,L"N");
				SetEvent(hEventAnswer);
				EnableWindow(hButtonF,FALSE);
			}break;
		case ID_BUTTONQ:
			{
				shutdown(client,SD_BOTH);
				closesocket(client);
				WSACleanup();
				DestroyWindow(hWnd);
			}break;
		case IDM_ABOUT:
			DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
			break;
		case IDM_EXIT:
			DestroyWindow(hWnd);
			break;
		default:
			return DefWindowProc(hWnd, message, wParam, lParam);
		}
		break;
	
	case WM_PAINT:
		{

		
		hdc = BeginPaint(hWnd, &ps);
		
		HDC hdcmem = CreateCompatibleDC(NULL);
		HBITMAP hbkground = LoadBitmap(hInst,MAKEINTRESOURCE(IDB_MOON));
		BITMAP bm;
		GetObject(hbkground,sizeof(bm),&bm);
		SelectObject(hdcmem,hbkground);
		BitBlt(hdc,0,0,bm.bmWidth,bm.bmHeight,hdcmem,0,0,SRCCOPY);
		// TODO: Add any drawing code here...
		EndPaint(hWnd, &ps);
		DeleteDC(hdcmem);
		DeleteObject(hbkground);
		}
		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	default:
		return DefWindowProc(hWnd, message, wParam, lParam);
	}
	return 0;
}

// Message handler for about box.
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
	UNREFERENCED_PARAMETER(lParam);
	switch (message)
	{
	case WM_INITDIALOG:
		return (INT_PTR)TRUE;

	case WM_COMMAND:
		if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
		{
			EndDialog(hDlg, LOWORD(wParam));
			return (INT_PTR)TRUE;
		}
		break;
	}
	return (INT_PTR)FALSE;
}

INT_PTR CALLBACK SignInProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
	UNREFERENCED_PARAMETER(lParam);
	switch (message)
	{
	case WM_INITDIALOG:
		return (INT_PTR)TRUE;

	case WM_COMMAND:
		int wId = LOWORD(wParam);
		switch (wId)
		{
		
		case IDOK:
			{
			LPTSTR temp;
			temp = new TCHAR[100];
			GetDlgItemText(hDlg, IDC_EDIT1,temp,100);
			_beginthread(threadRegister,0,temp);
			//================================================
			//Tat dialog
			EndDialog(hDlg,LOWORD(wParam));
			
			}
			break;
		case IDCANCEL:
			{
				SendMessage(hWnd,WM_DESTROY,0,0);
			}
			break;
		}
	}
	return (INT_PTR)FALSE;
}
